// Cz Exokernel 演示
// 展示如何在 Exokernel 上运行多个 LibOS

const std = @import("std");
const exo = @import("exokernel");

// ============ LibOS 1: 简单的批处理系统 ============
fn batch_libos_main() void {
    // 这是用户态的操作系统库
    // 可以实现自己的调度、内存管理等
    
    print("BatchOS: Starting...\n");
    
    // 通过系统调用分配内存
    const page_id = syscall_alloc_page();
    if (page_id != 0xFFFFFFFF) {
        print("BatchOS: Allocated page ");
        print_u32(page_id);
        print("\n");
        
        // 使用内存...
        
        // 释放内存
        _ = syscall_free_page(page_id);
        print("BatchOS: Freed page\n");
    }
    
    print("BatchOS: Done\n");
}

// ============ LibOS 2: 实时系统 ============
fn rtos_libos_main() void {
    print("RTOS: Starting real-time tasks...\n");
    
    var i: u32 = 0;
    while (i < 3) : (i += 1) {
        print("RTOS: Task iteration ");
        print_u32(i);
        print("\n");
        
        // 让出 CPU
        syscall_yield();
    }
    
    print("RTOS: Tasks completed\n");
}

// ============ LibOS 3: 数据库系统 ============
fn database_libos_main() void {
    print("DatabaseOS: Initializing storage...\n");
    
    // 分配多个页用于数据库
    var pages: [4]u32 = undefined;
    var i: u32 = 0;
    
    while (i < 4) : (i += 1) {
        pages[i] = syscall_alloc_page();
        if (pages[i] != 0xFFFFFFFF) {
            print("DatabaseOS: Allocated page ");
            print_u32(pages[i]);
            print("\n");
        }
    }
    
    print("DatabaseOS: Storage ready\n");
    
    // 清理
    i = 0;
    while (i < 4) : (i += 1) {
        if (pages[i] != 0xFFFFFFFF) {
            _ = syscall_free_page(pages[i]);
        }
    }
    
    print("DatabaseOS: Shutdown complete\n");
}

// ============ 系统调用包装 ============
fn syscall_alloc_page() u32 {
    // 实际应该通过中断或特殊指令
    // 这里简化为函数调用
    return 0; // 模拟
}

fn syscall_free_page(page_id: u32) u32 {
    _ = page_id;
    return 1;
}

fn syscall_yield() void {
    // 让出 CPU
}

// ============ 辅助函数 ============
fn print(msg: []const u8) void {
    std.debug.print("{s}", .{msg});
}

fn print_u32(value: u32) void {
    std.debug.print("{d}", .{value});
}

// ============ 主程序 ============
pub fn main() !void {
    std.debug.print("\n=== Cz Exokernel Demo ===\n\n", .{});
    
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    
    // 初始化 Exokernel
    var kernel = try exo.Exokernel.init(allocator, 16 * 1024 * 1024);
    defer kernel.deinit(allocator);
    
    std.debug.print("Exokernel initialized\n", .{});
    std.debug.print("Memory: 16 MB\n\n", .{});
    
    // 注册 LibOS
    const batch_id = kernel.register_libos("BatchOS", @intFromPtr(&batch_libos_main));
    const rtos_id = kernel.register_libos("RTOS", @intFromPtr(&rtos_libos_main));
    const db_id = kernel.register_libos("DatabaseOS", @intFromPtr(&database_libos_main));
    
    std.debug.print("Registered LibOS:\n", .{});
    if (batch_id) |id| std.debug.print("  - BatchOS (ID: {d})\n", .{id});
    if (rtos_id) |id| std.debug.print("  - RTOS (ID: {d})\n", .{id});
    if (db_id) |id| std.debug.print("  - DatabaseOS (ID: {d})\n\n", .{id});
    
    // 演示能力系统
    std.debug.print("=== Testing Capability System ===\n\n", .{});
    
    if (batch_id) |id| {
        // 为 BatchOS 分配页
        if (kernel.syscall_alloc_page(id)) |cap| {
            std.debug.print("BatchOS: Granted capability for page {d}\n", .{cap.id});
            
            // 尝试释放
            if (kernel.syscall_free_page(id, cap.id)) {
                std.debug.print("BatchOS: Successfully freed page\n", .{});
            }
        }
    }
    
    if (rtos_id) |id| {
        // 为 RTOS 分配页
        if (kernel.syscall_alloc_page(id)) |cap| {
            std.debug.print("RTOS: Granted capability for page {d}\n", .{cap.id});
            
            // 尝试让另一个 LibOS 释放（应该失败）
            if (batch_id) |other_id| {
                if (!kernel.syscall_free_page(other_id, cap.id)) {
                    std.debug.print("BatchOS: Correctly denied access to RTOS's page\n", .{});
                }
            }
            
            // RTOS 自己释放
            _ = kernel.syscall_free_page(id, cap.id);
        }
    }
    
    std.debug.print("\n=== Capability System Working! ===\n\n", .{});
    
    // 演示调度
    std.debug.print("=== Scheduling LibOS ===\n\n", .{});
    
    var round: u32 = 0;
    while (round < 3) : (round += 1) {
        std.debug.print("Round {d}:\n", .{round + 1});
        
        if (kernel.schedule()) |libos| {
            std.debug.print("  Running: {s}\n", .{libos.name[0..8]});
        }
        
        if (kernel.schedule()) |libos| {
            std.debug.print("  Running: {s}\n", .{libos.name[0..8]});
        }
        
        if (kernel.schedule()) |libos| {
            std.debug.print("  Running: {s}\n", .{libos.name[0..8]});
        }
        
        std.debug.print("\n", .{});
    }
    
    std.debug.print("=== Demo Complete ===\n", .{});
}
